package app.controller.wechat.scanlogin;

import app.entity.UserSession;
import app.utils.BasePathCollector;
import app.utils.Common;
import app.utils.DataResponse;
import app.utils.Md5;
import app.wechat.pojo.WeChat;
import com.scyf.bean.Oauth2AccessToken;
import com.scyf.bean.SnsUserInfo;
import com.scyf.weixintool.WeiXinAuthorization;
import com.swetake.util.Qrcode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import refactor.entity.User;
import refactor.mapper.UserMapper;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Controller
//该类用于进行微信的扫码登陆
public class Scan {
	@Autowired
	@Qualifier("wechat")
	private WeChat weChat;

	private UserMapper userMapper;

	@Autowired
	public void setUserMapper(UserMapper userMapper) {
		this.userMapper = userMapper;
	}

	@RequestMapping("/wechatlogin")
	public void wechatLogin(String mic,HttpServletResponse response,HttpServletRequest request) throws IOException{
		Map<String, Object> map=new HashMap<>();
		if(ScanStore.isCorrect(mic)){
			map.put("bool", true);
			map.put("url", BasePathCollector.getBasePathWithoutPort(request)+"3/index?mic="+mic);
			DataResponse.jsonResponse(response,map );
		}else {
			map.put("bool", false);
			map.put("url",BasePathCollector.getBasePathWithoutPort(request)+"login");
			DataResponse.jsonResponse(response,map );
		}
		
	}
	//是否过期
	@RequestMapping("/QRCOdeChecker")
	public void QRChecker(String mic, HttpServletResponse response) {
		boolean upto = ScanStore.isUpto(mic);
		Map<String, Object> map=new HashMap<>();
		if (upto) {
			map.put("flag", true);
			DataResponse.jsonResponse(response, map);
			return;
		}
		map.put("flag", false);
		DataResponse.jsonResponse(response, map);
		return;
	}
	
	@RequestMapping("/qrcode")
	public void QRCode(String mic, HttpServletRequest request,HttpServletResponse response) throws IOException{
		String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+weChat.getAppId()+"&redirect_uri="
				+ "https://www.3firelink.com/siotwx/scan4login?mic="+mic
				+ "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
		ScanStore.Machine(mic);
		BufferedImage bufImg = getBufImg(url);
		ByteArrayOutputStream output=new ByteArrayOutputStream();
		ImageIO.write(bufImg, "png", output);
		byte[] byteArray = output.toByteArray();
		ServletOutputStream out = response.getOutputStream();
		out.write(byteArray);
		out.flush();
	}
	
	@RequestMapping("/scan4login")
	public String scan4Login(String code, String mic,HttpServletResponse response,HttpServletRequest request, HttpSession session,Model model ) throws IOException{
		
		model.addAttribute("message", "确认登陆");
		model.addAttribute("flag", true);
		model.addAttribute("mic", mic);
		model.addAttribute("code", code);
		return "wxLoginmsg";
	}
	@RequestMapping("/dologin")
	public void dologin(HttpServletResponse response,String mic,String code){
		Oauth2AccessToken oauth2AccessToken = WeiXinAuthorization.getOauth2AccessToken(weChat.getAppId(),
				weChat.getAppSecret(), code);
		Map<String, Object> param = new HashMap<>();
		param.put("open_id", oauth2AccessToken.getOpenid());
		List<refactor.entity.User> userList = userMapper.selectByMap(param);
		if (userList!=null && !userList.isEmpty() && !ScanStore.isUpto(mic)) {
			if (userList.get(0).getRoleId() == 2) {
				ScanStore.changeMachine(mic);
				ScanStore.s.put(mic, new UserSession(userList.get(0)));
				param.clear();
				param.put("flag", 1);
				DataResponse.jsonResponse(response, param);
			}
			
		}else if (ScanStore.isUpto(mic)) {
			param.clear();
			param.put("flag", 0);
			DataResponse.jsonResponse(response, param);
		}else {
			param.clear();
			param.put("flag", -1);
			DataResponse.jsonResponse(response, param);
		}
		
		
	}
	@RequestMapping("/showCode")
	public String showCode(){
		return "QRCode";
	}
	
	@RequestMapping("/mic")
	public void macKey(HttpServletResponse response){
		Map<String, Object> map=new HashMap<>();
		String machineKey = machineKey();
		ScanStore.Machine(machineKey);
		map.put("mic", machineKey());
		DataResponse.jsonResponse(response, map);
	}
	
	@RequestMapping("/bindQRCode")
	public void bindQRCode(String code,HttpServletResponse response,HttpSession session) throws IOException{
		UserSession userSession= (UserSession) session.getAttribute(Common.sessionUser);
		String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+weChat.getAppId()+"&redirect_uri="
				+ "https://www.3firelink.com/siotwx/wechatbind?userid="+userSession.getId()
				+ "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
		
		BufferedImage bufImg = getBufImg(url);
		ServletOutputStream output = response.getOutputStream();
		ImageIO.write(bufImg, "png", output);
		output.flush();
	}
	
	@RequestMapping("/wechatbind")
	public String wechatbind(Integer userid, String code,Model model,HttpServletRequest request,HttpSession session){
		model.addAttribute("basePath", BasePathCollector.getBasePathWithoutPort(request));
		User user = userMapper.selectById(userid);
		if (user!=null&&(user.getOpenId()==null||"".equals(user.getOpenId()))) {
			Oauth2AccessToken oauth2AccessToken = WeiXinAuthorization.getOauth2AccessToken(weChat.getAppId(),
					weChat.getAppSecret(), code);
			user.setOpenId(oauth2AccessToken.getOpenid());
			SnsUserInfo snsUserInfo = WeiXinAuthorization.getSnsUserInfo(oauth2AccessToken.getAccess_token(), oauth2AccessToken.getOpenid());
			user.setAvatar(snsUserInfo.getHeadimgurl());
            userMapper.updateById(user);
			session.setAttribute(Common.sessionUser, new UserSession(user));
			
			model.addAttribute("message", "绑定成功");
		}else {
			model.addAttribute("message", "已经绑定用户");
		}
		return "bindmsg";
	}
	
	private String machineKey(){
		UUID randomUUID = UUID.randomUUID();
		return new Md5().getDigest(randomUUID.toString()+System.currentTimeMillis());
	}
	
	private BufferedImage getBufImg(String content) {

		BufferedImage bufImg = null;

		try {
			// 3-44
			// 4-64
			// 7-124
			// 8-154
			// 9-182
			// 10-216
			int size =11;// 二维码尺寸，取值范围1-40
			Qrcode qrcode = new Qrcode();
			qrcode.setQrcodeErrorCorrect('M');
			// 设置二维码排错率，可选L(7%)、M(15%)、Q(25%)、H(30%)，排错率越高可存储的信息越少，但对二维码清晰度的要求越小
			qrcode.setQrcodeEncodeMode('B');
			// 设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大
			qrcode.setQrcodeVersion(size);

			System.out.println(content);
			byte[] contentBytes = content.getBytes("utf-8");
			// 图片尺寸
			int imgSize = 67 + 12 * (size - 1);

			bufImg = new BufferedImage(imgSize, imgSize,
					BufferedImage.TYPE_INT_RGB);

			Graphics2D gs = bufImg.createGraphics();

			gs.setBackground(Color.WHITE);
			gs.clearRect(0, 0, imgSize, imgSize);

			// 设定图像颜色 &gt; BLACK
			gs.setColor(Color.BLACK);

			// 设置偏移量 不设置可能导致解析出错
			int pixoff = 2;
			// 输出内容 &gt; 二维码
			if (contentBytes.length > 0 && contentBytes.length < 800) {
				boolean[][] codeOut = qrcode.calQrcode(contentBytes);
				for (int i = 0; i < codeOut.length; i++) {
					for (int j = 0; j < codeOut.length; j++) {
						if (codeOut[j][i]) {
							gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
						}
					}
				}
			} else {
				System.err.println("QRCode content bytes length = "
						+ contentBytes.length);
			}

			gs.dispose();
			bufImg.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return bufImg;
	}
	
}
